//
//  HACChartNode.m
//  HStockCharts
//
//  Created by Hotacool on 2018/9/18.
//

#import "HACChartNode.h"
#import "HACBrushAxis.h"

@interface HACChartNode ()
@property (nonatomic, strong) HACBrushAxis *axisBrush;
@end

@implementation HACChartNode {
    CGFloat _labelHeight;//坐标label字高
}

- (instancetype)initWithHostLayer:(CALayer *)layer {
    if (self = [self init]) {
        self.hostLayer = layer;
        [self setUp];
    }
    return self;
}

- (void)setUp {
    self.xAxisCount = 5;
    self.yAxisCount = 5;
    _pointRect = CGRectZero;
    
    _leftAxis = [[HACAxisComponents alloc] init];
    _leftAxis.axisType = DrawingAxisTypeY;
    _leftAxis.labelCount = 5;
    _leftAxis.labelWidth = 40;
    _rightAxis = [[HACAxisComponents alloc] init];
    _rightAxis.axisType = DrawingAxisTypeY;
    _rightAxis.labelCount = 5;
    
    _axisBrush = [[HACBrushAxis alloc] initWithDataProvider:self];
}

- (void)setData:(HACChartData *)data {
    _data = data;
    [self calculateLimitValue];
}

- (void)refreshData:(HACChartData *)data {
    _data = data;
    [self calculateLimitValue];
}

- (void)clearNode {
    _data = nil;
}

- (CGFloat)maxContentWidth {
    return CGRectGetWidth(self.relativeFrame);
}

- (void)setNeedsDisplay {
    [self calculateLimitValue];
    if (self.hostLayer) {
        [self.axisBrush drawInLayer:self.hostLayer inRect:self.relativeFrame];
    }
}

- (void)removeNode {
    [self.axisBrush removeBrush];
}

- (void)setRelativeFrame:(CGRect)relativeFrame {
    _relativeFrame = relativeFrame;
    if (self.visualCount > 0) {
        [self updateFrame];
    }
}

- (void)setVisualCount:(NSInteger)visualCount {
    _visualCount = visualCount;
    if (visualCount > 0) {
        [self updateFrame];
    }
}

- (void)updateFrame {
    self.pointRect = self.relativeFrame;
    self.singleWidth = FormatValueWithRemain(self.pointRect.size.width / (self.visualCount - 1), 3);//两点成线，可见点间隔段为self.visualCount - 1
}

//偏移
- (NSInteger)relativeIdxFromIndex:(NSInteger)i {
    NSInteger idx = i - self.startIndex;
    NSInteger showCount = self.endIndex-self.startIndex+1;
    if (self.startIndex==0
        && showCount<self.visualCount) {
        //滑到最左端，已无历史数据时，显示最前端数据
        idx = self.visualCount-showCount+i;
    }
    return idx;
}

- (CGFloat)xPointForIndex:(NSInteger)index inRect:(CGRect)rect {
    CGFloat x = index * self.singleWidth + CGRectGetMinX(rect);
    return x;
}

- (CGFloat)calculatorYForValue:(CGFloat)value min:(CGFloat)min max:(CGFloat)max inRect:(CGRect)rect {
    if (value == kDrawingInvaildValue)
        return value;
    
    CGFloat relative = .0;
    if (min != max && value >= min && value <= max) {
        relative = ((max - value) / (max - min)) * CGRectGetHeight(rect);
    }
    else if (value < min) {
        // 超出下边边界做最小值处理
        relative = CGRectGetHeight(rect);
    }
    return CGRectGetMinY(rect) + relative;
}

#pragma mark - provider protocol
- (NSArray *)axisDatasInRect:(CGRect)rect {
    NSArray <HACAxisComponents *>* axixXDatas = [self xAxisDatasInRect:rect];
    NSArray <HACAxisComponents *>* axixYDatas = [self yAxisDatasInRect:rect];
    NSMutableArray *mergeArray = [NSMutableArray arrayWithArray:axixXDatas];
    [mergeArray addObjectsFromArray:axixYDatas];
    return mergeArray;
}

- (NSArray <HACAxisComponents *>*)xAxisDatasInRect:(CGRect)rect {
    NSInteger axisCount = self.xAxisCount;
    if (axisCount <= 0)
        return nil;
    
    NSMutableArray *xAxisDrawingData = [NSMutableArray array];
    // 从下往上
    for (int index = 0; index < axisCount; index++) {
        HACAxisComponents *axisItem = [[HACAxisComponents alloc] init];
        axisItem.index = index;
        axisItem.lineBolder = 0.5;
        axisItem.axisType = DrawingAxisTypeX;
        axisItem.queueLocation = CGQueueLocation(index, axisCount);
        CGFloat y = [self calculatorYForValue:index min:0 max:axisCount - 1 inRect:self.relativeFrame];
        [xAxisDrawingData addObject:axisItem];
        
        // x轴左边的默认值，按照最大值等分
        axisItem.text = [self stringForAxisTextItem:axisItem];
        if (!axisItem.text) // 如果没有返回使用默认值
        {
            CGFloat yValue = self.minValue + (ABS(self.maxValue - self.minValue) / (axisCount - 1)) * index;
            long digits = self.basicInfoData.priceDigits!=0?self.basicInfoData.priceDigits:0;
            //format
            if (self.leftAxis.customFormat) {
                @try {
                    axisItem.text = [NSString stringWithFormat:self.leftAxis.customFormat, yValue/pow(10, digits)];
                }
                @catch (NSException *exception) {
                    NSLog(@"Error: self.leftAxis.customFormat: %@", self.leftAxis.customFormat);
                }
            } else {
                axisItem.text = [NSString stringWithFormat:@"%.2f", yValue/pow(10, digits)];
            }
            axisItem.textFont = self.leftAxis.textFont;
            CGFloat midValue = self.minValue + (self.maxValue - self.minValue)/2;// openPrice
            //最大最小值红绿颜色
            if (yValue > midValue) {
                axisItem.textColor = [self colorWithValueType:DrawingUpValue];;
            } else if (yValue < midValue) {
                axisItem.textColor = [self colorWithValueType:DrawingDownValue];;
            } else {
                axisItem.textColor = RGB_HEX(kAxisTextColor);//[self colorWithValueType:DrawingEqualValue];;
            }
            yValue = (midValue>0)?(yValue - midValue)/midValue*100:0;
            axisItem.extText = [NSString stringWithFormat:@"%.2f%%", yValue];
            axisItem.extTextColor = axisItem.textColor?:RGB_HEX(kAxisTextColor);;
            axisItem.extTextFont = self.rightAxis.textFont;
        }
        
        CGSize textSize = [axisItem.text sizeWithAttributes:@{NSFontAttributeName : axisItem.textFont}];
        CGRect frame = CGRectMake(CGRectGetMinX(rect)+7, y, textSize.width , textSize.height);
        if (self.leftAxis.labelPosition == HACAxisLabelPositionOutside) {
            frame = CGRectMake(self.relativeFrame.origin.x - textSize.width - 4, y-_labelHeight/2, textSize.width , textSize.height);
        } else {
            if (axisItem.queueLocation == QueueLocationHead) {
                // 最下面一个下坐标对其线的位置
                frame.origin.y -= textSize.height;
            } else if (axisItem.queueLocation == QueueLocationTrail) {
                // 最上面一个上坐标对其线的位置
            } else {
                frame.origin.y -= textSize.height / 2; // 中间的跟线居中对齐
                axisItem.dashLengths = @[@2.0, @4.0];//中间虚线
                axisItem.lineBolder = 1;
                if (index == axisCount/2) {
                } else {//中间坐标值不显示
                    axisItem.text = @"";
                    axisItem.extText = @"";
                }
            }
        }
        axisItem.textFrame = frame;
        if (self.rightAxis.enable) {
            textSize = [axisItem.extText sizeWithAttributes:@{NSFontAttributeName : axisItem.extTextFont}];
            axisItem.extTextFrame = CGRectMake(rect.size.width-textSize.width-7, frame.origin.y, frame.size.width, frame.size.height);
        } else {
            axisItem.extText = nil;
            axisItem.extTextFrame = CGRectZero;
        }
        CGLine line;
        line = CGLineMake(self.relativeFrame.origin.x, y, CGRectGetMaxX(self.relativeFrame), y);
        axisItem.line = line;
        axisItem.lineColor = self.leftAxis.lineColor?:axisItem.lineColor;
    }
    return xAxisDrawingData;
}

- (NSArray <HACAxisComponents *>*)yAxisDatasInRect:(CGRect)rect {
    NSInteger axisCount = self.yAxisCount;
    if (axisCount <= 0)
        return nil;
    
    NSMutableArray *yAxisDrawingData = [NSMutableArray array];
    for (int index = 0; index < axisCount; index++) {
        if (index == 0 || index == axisCount - 1) {
            continue;
        }
        HACAxisComponents *axisItem = [[HACAxisComponents alloc] init];
        axisItem.index = index;
        axisItem.axisType = DrawingAxisTypeY;
        axisItem.queueLocation = CGQueueLocation(index, axisCount);
        CGFloat x = [self calculatorXForValue:index min:0 max:axisCount - 1 inRect:self.relativeFrame];
        CGLine line = CGLineMake(x, CGRectGetMinY(self.relativeFrame), x, CGRectGetMaxY(self.relativeFrame));
        axisItem.line = line;
        [yAxisDrawingData addObject:axisItem];
        
        // 计算坐标值，默认在最下面的x轴下面
        axisItem.text = [self stringForAxisTextItem:axisItem];
        if (!axisItem.text) {
            // 如果没有返回使用默认值
            axisItem.text = @"";
        }
        CGSize textSize = [axisItem.text sizeWithAttributes:@{NSFontAttributeName : axisItem.textFont}];
        CGRect frame = CGRectMake(x, CGRectGetMaxY(self.relativeFrame), textSize.width, textSize.height);
        if (axisItem.queueLocation == QueueLocationHead) {
            // 最左边一个左坐标对其线的位置
        } else if (axisItem.queueLocation == QueueLocationTrail) {
            // 最右面一个右坐标对其线的位置
            frame.origin.x -= textSize.width;
        } else {
            frame.origin.x -= textSize.width / 2; // 中间的跟线居中对齐
            axisItem.dashLengths = @[@2.0, @4.0];
        }
        axisItem.textFrame = frame;
    }
    return yAxisDrawingData;
}

- (NSString *)stringForAxisTextItem:(HACAxisComponents *)axisItem {
    return nil;
}

- (void)calculateLimitValue {
    CGFloat max = FLT_MIN;
    CGFloat min = FLT_MAX;
    self.maxValue = (max == FLT_MIN) ? .0 : max;
    self.minValue = (min == FLT_MAX) ? .0 : min;
}

- (CGFloat)calculatorXForValue:(CGFloat)value min:(CGFloat)min max:(CGFloat)max inRect:(CGRect)rect {
    if (value == kDrawingInvaildValue)
        return value;
    
    CGFloat relative = .0;
    if (min != max && value >= min && value <= max) {
        relative = ((value - min) / (max - min)) * CGRectGetWidth(rect);
    }
    else if (value > max) {
        // 超出右边边界做最大值处理
        relative = CGRectGetWidth(rect);
    }
    return CGRectGetMinX(rect) + relative;
}

- (UIColor *)colorWithValueType:(DrawingValueType)valueType {
    UIColor *color = RGB_HEX(kMainTextColor);
    switch (valueType) {
        case DrawingUpValue:
            color = RGB_HEX(kRedColor);
            break;
        case DrawingDownValue:
            color = RGB_HEX(kGreenColor);
            break;
        default:
            break;
    }
    return color;
}

#pragma mark -- api
- (NSInteger)indexAtChartForCoordinate:(CGPoint)point {
    return 0;
}

- (CGPoint)pointAtChartForIndex:(NSInteger)index {
    return CGPointZero;
}

- (HACChartDataEntry*)dataAtChartForCoordinate:(CGPoint)point {
    return nil;
}

- (HACChartDataEntry*)dataAtChartForIndex:(NSUInteger)index {
    return nil;
}
@end
